//
//  matrix.h
//  linear_algebra
//
//  Created by zhangnan on 2025/3/24.
//

#ifndef matrix_h
#define matrix_h

#include <stdio.h>
#include "../maths/fraction.h"

/**
 double 类型矩阵
 */
typedef struct{
    double *array;
    int rows;
    int cols;
} MATRIX_DOUBLE_TYPE;

/**
 int 类型矩阵
 */
typedef struct{
    int *array;
    int rows;
    int cols;
} MATRIX_INT_TYPE;

/**
 Fraction 类型矩阵
 */
typedef struct{
    FRACTION_TYPE **array;
    int rows;
    int cols;
} MATRIX_FRACTION_TYPE;


/**
 创建一个double类型矩阵
 */
MATRIX_DOUBLE_TYPE new_double_matrix(double *arr,int param_rows,int param_cols);

/**
 根据行列获取矩阵值（double）
 */
double get_value_from_double_matrix(MATRIX_DOUBLE_TYPE *matrix,int row_index,int col_index);



/**
 创建一个int类型的矩阵
 */
MATRIX_INT_TYPE new_int_matrix(double *arr,int param_rows,int param_cols);

/**
 根据行列获取矩阵值（int）
 */
int get_value_from_int_matrix(MATRIX_INT_TYPE *matrix,int row_index,int col_index);



// 释放 MATRIX_INT_TYPE 结构体占用的内存
void free_int_matrix(MATRIX_INT_TYPE* matrix);

// 动态创建 MATRIX_INT_TYPE 结构体
MATRIX_INT_TYPE* create_int_matrix(int rows, int cols);

// 释放 MATRIX_DOUBLE_TYPE 结构体占用的内存
void free_double_matrix(MATRIX_DOUBLE_TYPE* matrix);

// 动态创建 MATRIX_DOUBLE_TYPE 结构体
MATRIX_DOUBLE_TYPE* create_double_matrix(int rows, int cols);


/**
 * 创建一个分数矩阵
 * 
 * @param arr 一个指向分数数组的指针，用于初始化矩阵
 * @param param_rows 矩阵的行数
 * @param param_cols 矩阵的列数
 * @return 返回一个指向新创建的分数矩阵的指针
 * 
 * 此函数通过接受一个分数数组和矩阵的行列参数，创建并初始化一个分数矩阵
 * 它负责分配必要的内存，并通过复制给定数组中的值来填充矩阵
 */
MATRIX_FRACTION_TYPE* create_fraction_matrix(FRACTION_TYPE **arr,int param_rows,int param_cols);

/**
 创建一个全为0的矩阵
 */
MATRIX_FRACTION_TYPE *create_simple_fraction_matrix(int param_rows,int param_cols);

/**
 * 从分数矩阵中获取特定位置的值
 * 
 * @param matrix 一个指向分数矩阵的指针
 * @param row_index 目标值在矩阵中的行索引
 * @param col_index 目标值在矩阵中的列索引
 * @return 返回指向该位置的分数的指针
 * 
 * 此函数根据给定的行和列索引，从分数矩阵中检索特定位置的分数值
 * 它返回的是一个指向该分数的指针，而不是分数的副本
 */
FRACTION_TYPE* get_value_from_fraction_matrix(MATRIX_FRACTION_TYPE *matrix,int row_index,int col_index);

/**
 * 释放分数矩阵占用的内存
 * 
 * @param matrix 一个指向分数矩阵的指针
 * 
 * 此函数负责释放与分数矩阵相关的所有内存资源
 * 它是管理程序内存使用的必要步骤，以防止内存泄漏
 */
void free_fraction_matrix(MATRIX_FRACTION_TYPE *matrix);


/**
 * 打印分数矩阵
 */
void print_fraction_matrix(MATRIX_FRACTION_TYPE *matrix);

/**
 转换为阶梯型
 */
void trans_to_echelon(MATRIX_FRACTION_TYPE *matrix);


/**
 * 设置分数矩阵中的特定元素值
 * 
 * @param matrix 指向要设置值的分数矩阵
 * @param fraction 指向要设置值的分数矩阵
 * @param row_index 行索引，表示矩阵中的行位置
 * @param col_index 列索引，表示矩阵中的列位置
 * 
 * 此函数用于将分数矩阵中指定位置的元素设置为新的分数值通过行索引和列索引定位到具体位置
 */
void set_fraction_matrix_value(MATRIX_FRACTION_TYPE *matrix,FRACTION_TYPE *fraction,int row_index,int col_index);

/**
 * 获取分数矩阵中特定元素的值
 * 
 * @param matrix 指向分数矩阵的指针，从该矩阵中获取元素值
 * @param row_index 行索引，指定所需元素所在的行
 * @param col_index 列索引，指定所需元素所在的列
 * @return 返回指定位置的分数值如果位置无效，返回值是未定义的
 * 
 * 此函数用于从分数矩阵中获取指定位置的元素值通过行索引和列索引来定位元素位置
 */
FRACTION_TYPE * get_fraction_matrix_value(MATRIX_FRACTION_TYPE *matrix,int row_index,int col_index);

/**
 交换两列让行列式0较多的列放在后面
 */
MATRIX_FRACTION_TYPE* trans_zero_to_echelon(MATRIX_FRACTION_TYPE *matrix);
#endif /* matrix_h */
